
// ===============================================================================================================
// -*- C++ -*-
//
// AnimatedMesh.cpp - Animated mesh class.
//
// Copyright (c) 2011 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#include <MeshLib.hpp>
#include <algorithm> // For std::lexicographical_compare()

// Used as predicate in std::sort.
static bool SortByFileName(const std::string & a, const std::string & b)
{
	const size_t a_length = a.length();
	const size_t b_length = b.length();

	if (a_length < b_length)
	{
		return (true);
	}
	else if (a_length > b_length)
	{
		return (false);
	}
	else
	{
		return (std::lexicographical_compare(a.c_str(), a.c_str() + a_length, b.c_str(), b.c_str() + b_length));
	}
}

namespace MeshLib {

AnimatedMesh::AnimatedMesh(const char * dirWithMeshes, int frameRate) : timeCount(0), currentFrame(0), nextFrame(0)
{
	this->frameRate = frameRate;
	this->maxTime = (1.0f / frameRate);

	assert(dirWithMeshes != 0);

	Mesh * mesh;
	char path[FILENAME_MAX];

	strncpy(path, dirWithMeshes, FILENAME_MAX);
	size_t len = strlen(path);

	if (path[len] != '/')
	{
		path[len] = '/';
	}

	// Set the ext we are looking for...
	path[len + 1] = '*';
	path[len + 2] = '.';
	path[len + 3] = 'o';
	path[len + 4] = 'b';
	path[len + 5] = 'j';
	path[len + 6] = 0;

	char * fileName = CommLib::FileFindFirst(path, 0, (FILE_HIDDEN | FILE_SUBDIR | FILE_SYSTEM));

	if (!fileName)
	{
		CommLib::DbgPrintf(PRINT_ERROR, "No valid files were found for an AnimatedMesh in dir: \"%s\"", dirWithMeshes);
		return;
	}

	// All the files present in the dir. We will order by name.
	std::vector<std::string> files;

	while (fileName != 0)
	{
		files.push_back(fileName);
		fileName = CommLib::FileFindNext(0, (FILE_HIDDEN | FILE_SUBDIR | FILE_SYSTEM));
	}

	CommLib::FileFindClose();

	std::sort(files.begin(), files.end(), SortByFileName);

	for (size_t i = 0; i < files.size(); ++i)
	{
		mesh = new Mesh;
		MeshLib::MeshFromWavefrontObject(files[i].c_str(), mesh);
		keyFrames.push_back(mesh); // New frame to the animation
	}
}

void AnimatedMesh::Animate(float deltaTime)
{
	assert(!keyFrames.empty());

	const int maxFrames = (keyFrames.size() - 1);
	timeCount += deltaTime;

	// Move to next frame:
	if (timeCount >= maxTime)
	{
		timeCount = 0.0f;
		++currentFrame;
		++nextFrame;

		if (currentFrame > maxFrames)
		{
			currentFrame = 0;
		}

		if (nextFrame > maxFrames)
		{
			nextFrame = 0;
		}
	}
}

AnimatedMesh::~AnimatedMesh(void)
{
	for (size_t i = 0; i < keyFrames.size(); ++i)
	{
		delete keyFrames[i];
	}

	keyFrames.clear();
}

}; // namespace MeshLib {}